<template>
    <ATreeSelect
        ref="se"
        v-model="ownValue"
        v-bind="{ placeholder: '请选择', ...$attrs }"
        :tree-data="_treeData"
        :show-search="showSearch"
        allow-clear
        :tree-node-filter-prop="treeNodeFilterProp"
        v-on="{ ...$listeners, change: change, select: select }"
    >
        <slot />
    </ATreeSelect>
</template>

<script>
import { getVal } from '@/utils'
function getSelectOptionsVTree(
    arr = [],
    {
        title = "name",
        value = "id",
        children = "child",
        key = "key",
        disabled = "disabled",
    } = {},
    extra = {},
    useKey = false,
    pids = []
) {
    if (!Array.isArray(arr)) return arr;
    return arr.map((item) => {
        const _extra = typeof extra === "function" ? extra(item) : extra;
        const _pids = pids.concat([item[value]]);
        const _value = useKey ? key : value;
        const _key = _pids.join("-");
        const obj = { ...item, ..._extra, key: _key };
        return {
            ..._extra,
            key: _key,
            title: obj[title],
            label: obj[title],
            value: obj[_value],
            disabled: obj[disabled],
            _origin: { ...item },
            children: getSelectOptionsVTree(
                obj[children],
                { title, value, children, key, disabled },
                extra,
                useKey,
                _pids
            ),
        };
    });
}
export default {
    model: {
        prop: "value",
        event: "change",
    },
    props: {
        value: [String, Array, Number],
        treeData: {
            type: Array,
            default: () => [],
        },
        fields: Object,
        treeNodeFilterProp: {
            type: String,
            default: "title",
        },
        showSearch: {
            type: Boolean,
            default: true,
        },
        extra: [Object, Function],
        getOriginValue: {
            type: Boolean,
            default: true,
        },
        useKey: {
            type: Boolean,
            default: true,
        },
        pids: {
            type: Array,
            default: () => [],
        },
    },
    data() {
        return {
            ownValue: undefined,
            selectNode: undefined,
            expandedKeys: [],
        };
    },
    computed: {
        _treeData() {
            return getSelectOptionsVTree(
                this.treeData,
                this._fields,
                this.extra,
                this.useKey,
                this.pids
            );
        },
        _fields() {
            return {
                title: "name",
                value: "id",
                children: "children",
                key: "key",
                ...this.fields,
            };
        },
    },
    watch: {
        value: {
            handler() {
                this.getOwnValue();
            },
            immediate: true,
        },
        _treeData: {
            handler() {
                this.getOwnValue();
            },
            immediate: true,
        },
    },
    methods: {
        change(value, label, extra) {
            const _value = this.getValue(value);
            // console.log(_value);
            this.$emit("change", _value, label?.[0], this.selectNode, extra);
        },
        select(value, node, extra) {
            const _value = this.getValue(value);
            this.selectNode = getVal(node, "dataRef._origin");
            this.$emit("select", _value, node, extra);
        },
        getValue(value) {
            if (Array.isArray(value))
                return this.useKey && this.getOriginValue
                    ? value.map((i) => i?.split("-").pop())
                    : value;
            return this.useKey && this.getOriginValue
                ? value?.split("-").pop()
                : value;
        },
        findItem(arr, val, { value, key }) {
            let _val = undefined;
            if (Array.isArray(arr) && arr.length) {
                // console.log(value, key, 'arr');
                arr.some((i) => {
                    if (`${i._origin?.[value]}` === `${val}`) {
                        _val = i;
                    } else {
                        _val = this.findItem(i.children, val, { value, key });
                    }
                    if (_val) this.expandedKeys.push(i?.[this._fields.key]);
                    return !!_val;
                });
            }
            return _val;
        },
        getOwnValue() {
            if (this.useKey && this.getOriginValue) {
                if (this.value) {
                    this.ownValue = Array.isArray(this.value)
                        ? this.value.map(
                              (i) =>
                                  this.findItem(
                                      this._treeData,
                                      i,
                                      this._fields
                                  )?.[this._fields.key]
                          )
                        : this.findItem(
                              this._treeData,
                              this.value,
                              this._fields
                          )?.[this._fields.key];
                } else {
                    this.ownValue = undefined;
                }
            } else {
                this.ownValue = this.value;
            }
        },
    },
};
</script>
